extern crate reqwest ;//https 客户端访问
extern crate select;//页面解析

use std::io::Read;
use std::fs::File;
//use std::fs::create_dir_all;

//use std::io::{BufWriter};

use select::document::Document;
use select::predicate::{ Predicate, Attr, Class, Name};

use std::error::Error;
use std::io::prelude::*;
use std::{thread, time};
use std::path::Path;
//命令行解析
use structopt::StructOpt;


use reqwest::header::HeaderMap;
//命令行解析
#[derive(StructOpt)]
struct Opt {
    /// The pattern to look for
    /// 页面路径
    #[structopt(short ="u", long ="url")]
    url: String,
    /// The path to the file to read
    /// 保存目录 通过 from_os_str 转出 std::path::PathBuf类型
    #[structopt(parse(from_os_str),short ="p", long ="path")]
    path: std::path::PathBuf,
}

//ex https://movie.douban.com/celebrity/1339438/photos/
//cargo run -- -u https://movie.douban.com/celebrity/1339438/photos/ -p g:/download3
fn main() {
    //命令行解析
    let opt = Opt::from_args();
    //命令行解析
    println!("url={},path={}", opt.url,opt.path.to_str().unwrap());

    

    //首页解析
    let response =get_html(&opt.url); 
    println!("response={}",&response);

    parse_html(&response,opt.path.to_str().unwrap());
    /*
    let document = Document::from(response.as_str());
    let countnode =document.find(Class("count")).next().unwrap();
    println!("count={}",countnode.text().replace("(共", "").replace("张)", ""));

    let count =countnode.text().replace("(共", "").replace("张)", "").parse::<i32>().unwrap();
     */
}

fn get_html(url : &String) -> String {
    let mut headers = HeaderMap::new();
    headers.insert("Content-Type", " text/html;charset=UTF-8".parse().unwrap());
    headers.insert("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36".parse().unwrap());
    
   let mut file = std::fs::File::open("cookie.txt").unwrap();
   let mut contents = String::new();
   file.read_to_string(&mut contents).unwrap();
    
    headers.insert("Cookie",contents.parse().unwrap());

    

    let response = reqwest::Client::builder()
    .default_headers(headers)
    .danger_accept_invalid_certs(true)
    .build()
    .expect("客户端创建失败")
    .get(&*url)
    .send();

    let mut  responseStr =String::from("");
    match response {
        Ok(mut r) => {

            responseStr =String::from( r.text().unwrap() )
        
        }
        Err(e) => {
           println!("{:?}",e);
        }
    }

    responseStr

}
//解析页面
fn parse_html(html : &String,path :&str) {
    let document = Document::from(html.as_str());

    //页面图片解析
    for node in document.find(Class("cover").descendant(Name("img"))) {
        println!("imgurl={}",node.attr("src").unwrap());
        println!("largeimgurl={}",node.attr("src").unwrap().replace("/m/","/l/"));
        let largeimgurl =node.attr("src").unwrap().replace("/m/","/l/");
        //下载大图
        downloadfile(&largeimgurl,&path);

        let sleep_time = time::Duration::from_millis(1000*10);
        thread::sleep(sleep_time);
    }

    //跳转下一页
    for node  in  document.find(Class("next").descendant(Name("a"))) {
        println!("nexturl={}",node.attr("href").unwrap());

        let response =get_html(&node.attr("href").unwrap().to_string());

        let sleep_time = time::Duration::from_millis(1000*10);
        thread::sleep(sleep_time);

        parse_html(&response,&path);
    }
}
//下载文件
fn downloadfile(url: &String ,path :&str) {
    let mut response =  reqwest::Client::builder()
    .danger_accept_invalid_certs(true)
    .build()
    .expect("客户端创建失败")
    .get(&*url)
    .send();

    match response {
        Ok(mut r) => {

            let filename =std::path::Path::new(&url).file_name().unwrap().to_str().unwrap();

            let mut file = std::fs::File::create(format!("{}/{}",path.to_owned(),filename.to_owned())).unwrap();
            r.copy_to(&mut file).unwrap();
        
            let sleep_time = time::Duration::from_millis(1000*1);
            thread::sleep(sleep_time);
        }

        Err(e) => {
           println!("{:?}",e);
        }
    }
    


}